#include <caml/alloc.h>
#include <caml/memory.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>
#include <math.h>
//#include <stdio.h>
//#include <string.h>

//#include "math_num.h"
double fminbr(				// An estimate to the min location
	const double ax,		// Specify the interval the minimum
	const double bx,		// to be sought in
	double (*f)(double, void*),		// Function under investigation
    void* user_data,
	const double tol);		// Acceptable tolerance


void evalfunc_helper(double* fx, value* f, double x)
{
    CAMLparam0();
    CAMLlocal2(vx, vret);
    vx = caml_copy_double(x);
    vret = callback(*f, vx);
    *fx = Double_val(vret);
    CAMLreturn0;
}

double evalfunc(double x, void* user_data)
{
    double fx;
    value* f = (value *)user_data;
    evalfunc_helper(&fx, f, x);
    return fx;
}


CAMLprim value c_fminbr(value vax, value vbx, value vf, value vtol)
{
    CAMLparam4(vax, vbx, vf, vtol);
    CAMLlocal1(vret);

    double ax = Double_val(vax);
    double bx = Double_val(vbx);
    double tol = Double_val(vtol);
    double ret;

    ret = fminbr(ax, bx, evalfunc, &vf, tol);
    CAMLreturn(caml_copy_double(ret));
}

